import os

import pandas as pd

from module.static_module.parent.model import AdditionModule
from core.constant import *
from core.k_manage import BarGenerator, BGContainer
from core.object import BarData
from module.logic_module.exchange_server.data_server import HistoryData
from tools.framework import gen_result_folder_name, load_module_from_path, get_ui_value


class DataMergeModel(AdditionModule):
    def __init__(self, master):
        super().__init__(master, Module.DataMerge)
        # 实体类映射视图类变量数据
        self.data_name_ls = []
        self.k_interval_ls = []
        self.start_time_ls = []
        self.end_time_ls = []
        # 映射视图类变量数据到实体类
        self.data_name = None
        self.k_interval = None
        self.start_time = None
        self.end_time = None
        # 必要结构变量
        self.bg_container = BGContainer()
        self.data_dc: dict[str, pd.DataFrame] = {}
        self.ori_interval = None
        self.count = 0
        # 实体类结构变量
        self.sub_view = None

    def sec_init(self):
        self.data_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.Mk.value]
        self.k_interval_ls = [mem.value for mem in Interval]
        self.start_time_ls = []
        self.end_time_ls = []
        from module.addition_module.data_merge.view import DataMergeView
        self.sub_view = DataMergeView(self)
        pass

    def get_ui_params(self):
        # 获取ui界面的相关参数
        values, indices = self.sub_view.auto_layout.get_value(LabelMember.DataName)
        self.data_name = get_ui_value(values, indices, WidgetCategory.Combobox)
        values, indices = self.sub_view.auto_layout.get_value(LabelMember.KInterval)
        k_interval = get_ui_value(values, indices, WidgetCategory.Combobox)
        for mem in Interval:
            if mem.value == k_interval:
                self.k_interval = mem
                break
        values, indices = self.sub_view.auto_layout.get_value(LabelMember.StartTime)
        self.start_time = get_ui_value(values, indices, WidgetCategory.Entry)
        values, indices = self.sub_view.auto_layout.get_value(LabelMember.EndTime)
        self.end_time = get_ui_value(values, indices, WidgetCategory.Entry)

    def on_data_name_change(self):
        values, indices = self.sub_view.auto_layout.get_value(
            LabelMember.DataName)
        self.data_name = get_ui_value(values, indices, WidgetCategory.Combobox)
        start_end_time = self.master.file_manager.describe_all_dc[self.data_name].start_end_time_ls
        self.start_time_ls = [start_end_time[0]]
        self.end_time_ls = [start_end_time[1]]
        pass

    def on_run(self):
        # 点击运行按钮回调
        self.get_ui_params()

        self.merge()

    def merge(self):
        from tools.file_manager import gen_data_name

        data_path = self.master.file_manager.describe_all_dc[self.data_name].path
        self.ori_interval = self.master.file_manager.describe_all_dc[self.data_name].interval_val
        start_time = pd.to_datetime(self.start_time)
        end_time = pd.to_datetime(self.end_time)

        his_data_server = HistoryData(self)
        his_data_server.only_traverse(data_path, self.on_node, self.on_base_bar,
                                      start_time=start_time, end_time=end_time)
        # 保存data_dc的值
        csv_name = gen_data_name(DataCategory.Mk) + ".csv"
        data_path = os.path.join(self.master.file_manager.market_data_path, csv_name)
        self.master.file_manager.save_dc_csv(self.data_dc, path=data_path)

    def on_window_bar(self, bar: BarData):
        bar_sr = bar.to_sr()
        symbol = bar.symbol
        if symbol not in self.data_dc.keys():
            self.data_dc[symbol] = pd.DataFrame([], columns=bar_sr.index)
        self.data_dc[symbol].loc[bar_sr.name] = bar_sr.values
        self.count += 1
        if self.count % 2000 == 0:
            info = f"已处理数据{self.count}条，至{bar.datetime.strftime('%Y-%m-%d %H:%M')}。"
            self.master.file_manager.log_engine.emit(info, LogName.Running)

    def on_node(self, node_dc: dict):
        pass

    def on_base_bar(self, base_bar: BarData):
        is_fund = self.bg_container.update(base_bar)
        if is_fund:
            # bg_ins = self.bg_container.get(symbol=base_bar.symbol, interval=self.k_interval)
            # bg_ins.update_bar(base_bar)
            pass
        else:
            bg_ins = BarGenerator(base_bar.symbol, self.k_interval, self.on_window_bar)
            bg_ins.update_bar(base_bar)
            self.bg_container.place(bg_ins)
            pass

        pass



